package insta.project.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;

/**
 * Utilities for loading a bitmap from a URL
 * 
 */
public class ImageHelper {

	private static final String TAG = "Panoramio";

	private static final int IO_BUFFER_SIZE = 4 * 1024;

	/**
	 * Loads a bitmap from the specified url. This can take a while, so it
	 * should not be called from the UI thread.
	 * 
	 * @param url
	 *            The location of the bitmap asset
	 * 
	 * @return The bitmap, or null if it could not be loaded
	 */
	public static Bitmap loadBitmap(String url) {
		Bitmap bitmap = null;
		InputStream in = null;
		BufferedOutputStream out = null;

		try {
			in = new BufferedInputStream(new URL(url).openStream(),
					IO_BUFFER_SIZE);

			final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
			out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
			copy(in, out);
			out.flush();

			final byte[] data = dataStream.toByteArray();
			bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
		} catch (IOException e) {
			Log.e(TAG, "Could not load Bitmap from: " + url);
		} finally {
			closeStream(in);
			closeStream(out);
		}

		return bitmap;
	}

	/**
	 * Loads a bitmap from the specified url. This can take a while, so it
	 * should not be called from the UI thread.
	 * 
	 * @param currentImageResource
	 *            The location of image resource
	 * @param ContentResolver
	 *            Content solver from top level
	 * 
	 * @return The bitmap, or null if it could not be loaded
	 */
	public static Bitmap getBitmapFromUri(String currentImageResource,
			ContentResolver crContentResolver) {
		/*
		 * We know its a string, should we try local or remote image fetching ?
		 */
		Bitmap input = null;
		if (currentImageResource.contains("http://")) {
			Log.d("ImageHelper.getBitmapFromUri()", "Loading external image "
					+ currentImageResource);
			if (currentImageResource.contains(".jpg")
					|| currentImageResource.contains(".png")) {

				// Try first to load from sdCard, if content is cached
				// FIXME : loading doesn't works
				String strFileName = new File(currentImageResource).getName();
				String localImageResource = "track_pictures/" + strFileName;
				input = ImageHelper.getImageFromSdCard(localImageResource,
						crContentResolver);
				try {
					input = MediaStore.Images.Media.getBitmap(
							crContentResolver, Uri.parse(localImageResource));
				} catch (Exception e) {
					e.printStackTrace();
				}
				/*
				 * Local image is not stored yet, fetch it from www and store it
				 * on sdcard for caching purposes
				 */
				if (input == null) {
					input = ImageHelper.loadBitmap(currentImageResource);
					// Save image on sd-card to avoid $GET request
					// overload
					// Remove all www related infos
					String strDestination = currentImageResource.replace(
							"http://www.freebangers.com/__files/", "");
					Log.d("ImageHelper.getBitmapFromUri", "Storing "
							+ strDestination + " on sdcard for caching purpose");
					FileHelper.saveImageToSdCard(strDestination, input);
				} else {
					Log.d("ImageHelper.getBitmapFromUri()", "Image "+currentImageResource+" loaded from sdcard cache with success");
				}
			}
		} else {
			input = ImageHelper.getImageFromSdCard(currentImageResource,
					crContentResolver);
		}
		return input;
	}

	public static Bitmap getImageFromSdCard(String currentImageResource,
			ContentResolver crContentResolver) {
		Bitmap input = null;
		try {
			input = MediaStore.Images.Media.getBitmap(crContentResolver,
					Uri.parse(currentImageResource));
		} catch (FileNotFoundException e) {
			Log.d("getBitmapFromUri.ImageHelper", "Can't find the file"
					+ currentImageResource);
		} catch (IOException e) {
			Log.d("getBitmapFromUri.ImageHelper",
					"An input/output exception occur");
		}
		return input;
	}

	/**
	 * UTILITY FUNCTIONS
	 */
	/**
	 * Closes the specified stream.
	 * 
	 * @param stream
	 *            The stream to close.
	 */
	private static void closeStream(Closeable stream) {
		if (stream != null) {
			try {
				stream.close();
			} catch (IOException e) {
				android.util.Log.e(TAG, "Could not close stream", e);
			}
		}
	}

	/**
	 * Copy the content of the input stream into the output stream, using a
	 * temporary byte array buffer whose size is defined by
	 * {@link #IO_BUFFER_SIZE}.
	 * 
	 * @param in
	 *            The input stream to copy from.
	 * @param out
	 *            The output stream to copy to.
	 * @throws IOException
	 *             If any error occurs during the copy.
	 */
	private static void copy(InputStream in, OutputStream out)
			throws IOException {
		byte[] b = new byte[IO_BUFFER_SIZE];
		int read;
		while ((read = in.read(b)) != -1) {
			out.write(b, 0, read);
		}
	}
}
